<template>
  <div>
    <div class="h-100 page-box flex-column">
      <div class="btns-line">
        <el-button
          type="primary"
          icon="el-icon-plus"
          @click="$router.push('/formManage/dataSource')"
          >数据源管理</el-button
        >
        <el-button type="primary" icon="el-icon-plus" @click="showAddAPI"
          >新增API</el-button
        >
      </div>
      <div class="flex-1 flow-y-auto">
        <data-table
          ref="table"
          :pageObj="params"
          @modifyItem="modifyItem"
          @deleteItem="deleteItem"
          element-loading-text="加载中..."
          height="580"
          v-bind="tableOptions"
          v-loading="tableLoading"
          :updateCallback="getApiList"
        ></data-table>
      </div>
    </div>
    <el-dialog
      :visible.sync="createApiVisible"
      :title="dialogTitle"
      :close-on-click-modal="false"
      @close="dialogClose"
      custom-class="selfDialog"
      width="500px"
      v-loading="dialogLoading"
    >
      <el-form ref="form" :model="form" label-width="110px">
        <el-form-item
          prop="interfaceName"
          label="名称"
          :rules="rules.interfaceName"
        >
          <el-input
            v-model="form.interfaceName"
            placeholder="请输入名称"
          ></el-input>
        </el-form-item>
        <el-form-item
          prop="connectionType"
          label="连接类型"
          :rules="rules.connectionType"
        >
          <el-select
            ref="select"
            v-model="form.connectionType"
            @change="connectionTypeChange"
            placeholder="请选择连接类型"
            style="width: 100%;"
          >
            <el-option label="RestFul类型" :value="1"></el-option>
            <el-option label="Mysql类型" :value="2"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item
          prop="dataSourceId"
          label="数据源"
          :rules="rules.dataSourceId"
        >
          <el-select
            v-model="form.dataSourceId"
            placeholder="请选择数据源"
            style="width: 100%;"
          >
            <el-option
              v-for="item in dataSourceFilterList"
              ref="dataSourceSelect"
              :key="item.dataSourceId"
              :value="item.dataSourceId"
              :label="item.dataSourceName"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item
          prop="extraUrl"
          label="补充路径"
          :rules="rules.extraUrl"
          v-if="form.connectionType === 1"
        >
          <el-input
            v-model="form.extraUrl"
            placeholder="请输入补充路径"
          ></el-input>
        </el-form-item>
        <el-form-item
          prop="method"
          label="请求方式"
          :rules="rules.method"
          v-if="form.connectionType === 1"
        >
          <el-select
            v-model="form.method"
            placeholder="请选择请求方式"
            style="width: 100%;"
          >
            <el-option label="get" :value="1"></el-option>
            <el-option label="post" :value="2"></el-option>
            <el-option label="put" :value="3"></el-option>
            <el-option label="delete" :value="4"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item
          prop="requestBody "
          label="请求体"
          :rules="rules.extraUrl"
          v-if="
            form.connectionType === 1 &&
              (form.method === 2 || form.method === 3)
          "
        >
          <el-input
            v-model="form.requestBody"
            placeholder="请输入请求体"
          ></el-input>
        </el-form-item>
        <el-form-item
          prop="sqlScript"
          label="sql语句"
          :rules="rules.sqlScript"
          v-if="form.connectionType === 2"
        >
          <el-input
            type="textarea"
            v-model="form.sqlScript"
            placeholder="请输入sql语句"
          ></el-input>
        </el-form-item>
        <el-form-item
          prop="bugReset"
          v-if="form.connectionType === 2"
          v-show="false"
        ></el-form-item>
        <el-form-item prop="dataProcess" label="数据处理函数">
          <el-input
            type="textarea"
            v-model="form.dataProcess"
            placeholder="请输入数据处理函数"
          ></el-input>
        </el-form-item>
      </el-form>
      <div class="text-right">
        <el-button @click="testInvokeInterface" type="primary"
          >接口测试</el-button
        >
      </div>
      <el-form ref="testForm" :model="testForm" label-width="110px">
        <el-form-item label="接口参数" prop="params" :rules="paramsRule">
          <el-input
            v-model="testForm.params"
            placeholder='{"page": 1, "size": 10, "name": "张三"}'
          ></el-input>
        </el-form-item>
        <el-form-item label="返回数据" prop="callData">
          <el-input v-model="testForm.callData" type="textarea"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="createApiVisible = false" size="mini"
          >取消</el-button
        >
        <el-button @click="subForm" size="mini" type="primary">确定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import {
  getApiList,
  setApiItem,
  delApiItem,
  getDataSourceList,
  invokeInterTest
} from "@/api/formApi";
import { validateIllegality } from "@/utils/validate";
import { confirm } from "@/utils/tools";

export default {
  name: "apiManage",
  data() {
    let paramsRuls = (rule, value, callback) => {
      if (value) {
        if (value.length && value.length > 2000) {
          callback(new Error("参数长度不能大于 2000 个字符"))
        }
        try {
          JSON.parse(value);
          callback();
        } catch {
          callback(new Error("参数格式不正确"));
        }
      }
      callback();
    };

    return {
      params: {
        page: 1,
        size: 10,
        total: 0
      },
      searchData: {
        factoryId: window.localStorage.factoryId
      },
      tableLoading: false,
      tableOptions: {
        tableData: [],
        modifySettings: [
          {
            eventName: "modifyItem",
            name: "编辑",
            btnType: "",
            code: "mes-systemConfig-middleWare-btn_edit"
          },
          {
            eventName: "deleteItem",
            name: "删除",
            btnType: "danger",
            code: "mes-systemConfig-middleWare-btn_edit"
          }
        ],
        _columns: [
          {
            prop: "interfaceName",
            label: "接口名称"
          },
          {
            prop: "connectionTypeLabel",
            label: "数据源连接类型"
          },
          {
            prop: "dataSourceLabel",
            label: "数据源"
          }
        ]
      },
      form: {
        dataProcess: null,
        connectionType: 1,
        dataSourceId: null,
        extraUrl: null,
        factoryId: window.localStorage.factoryId,
        interfaceName: null,
        method: 1,
        requestBody: null,
        sqlScript: null,
        bugReset: null
      },
      rules: {
        interfaceName: [
          {
            required: true,
            min: 1,
            max: 64,
            message: "请输入64个字符以内的名称",
            trigger: "blur"
          },
          { validator: validateIllegality, trigger: "blur" }
        ],
        connectionType: {
          required: true,
          trigger: "blur",
          message: "请选择连接类型"
        },
        dataSourceId: {
          required: true,
          trigger: "blur",
          message: "请选择数数据源"
        },
        method: {
          required: true,
          trigger: "blur",
          message: "请选择数据源类型"
        },
        sqlScript: { required: true, max: 2000, trigger: "blur", message: "请输入不大于 2000 个字符的sql语句" },
        extraUrl: {max: 2000, message: '长度不能超过 2000 个字符', trigger: "blur"},
      },
      paramsRule: { validator: paramsRuls, trigger: "blur" },
      dialogTitle: "新建接口",
      createApiVisible: false,
      dataSourceFilterList: [],
      dataSourceList: [],
      getDataEnd: false,
      testForm: {
        params: null,
        callData: null
      },
      dialogLoading: false
    };
  },
  created() {
    this.getApiList();
    this.getDataSourceList();
  },
  watch: {
    "form.connectionType"(val) {
      this.filterDataSourceList(this.form.connectionType);
      this.$refs.form && this.$refs.form.clearValidate();
    }
  },
  methods: {
    getApiList() {
      this.tableLoading = true;
      getApiList(this.params, this.searchData).then(res => {
        this.tableLoading = false;
        this.tableOptions.tableData = res.data.rows;
        this.params.total = res.data.total;
        this.tableOptions.tableData.forEach(
          item =>
            (item.connectionTypeLabel =
              item.connectionType === 1 ? "RestFul连接" : "Mysql连接")
        );
        if (this.params.page > 1 && res.data.rows.length === 0) {
          this.params.page--;
          this.getApiList();
        }
        if (this.getDataEnd) {
          this.tableOptions.tableData.forEach(item => {
            this.$set(
              item,
              "dataSourceLabel",
              this.dataSourceList.find(
                one => item.dataSourceId === one.dataSourceId
              ).dataSourceName
            );
          });
        }
        this.getDataEnd = true;
      }).catch(err => {
        this.tableLoading = false
      })
    },
    modifyItem(item) {
      this.isEdit = true;
      this.dialogTitle = "编辑接口";
      this.createApiVisible = true;
      this.form = Object.assign({}, item);
      this.filterDataSourceList(1);
    },
    deleteItem(item) {
      confirm("删除之后会影响相关接口且不可撤销，是否确定？").then(res => {
        delApiItem({ dataInterfaceId: item.dataInterfaceId }).then(res => {
          this.$message({
            type: "success",
            message: "删除成功"
          });
          this.getApiList();
        });
      });
    },
    showAddAPI() {
      this.isEdit = false;
      this.createApiVisible = true;
      this.dialogTitle = "新建接口";
      this.filterDataSourceList(1);
    },
    connectionTypeChange() {
      this.form.dataSourceId = null;
    },
    getDataSourceList() {
      getDataSourceList(
        { page: 1, size: 9999 },
        { factoryId: window.localStorage.factoryId }
      ).then(res => {
        this.dataSourceList = res.data.rows;
        if (this.getDataEnd) {
          this.tableOptions.tableData.forEach(item => {
            this.$set(
              item,
              "dataSourceLabel",
              this.dataSourceList.find(
                one => item.dataSourceId === one.dataSourceId
              ).dataSourceName
            );
          });
        }
        this.getDataEnd = true;
      });
    },
    filterDataSourceList(type) {
      this.dataSourceFilterList = this.dataSourceList.filter(
        item => item.connectionType === type
      )
    },
    subForm() {
      this.$refs.form.validate(valid => {
        if (valid) {
          this.dialogLoading = true
          this.form.factoryId = window.localStorage.factoryId;
          setApiItem(this.form).then(res => {
            this.getApiList();
            this.createApiVisible = false;
          }).catch(err => {
            this.dialogLoading = false
          });
        } else {
          return false;
        }
      })
    },
    dialogClose() {
      this.form = {
        dataProcess: null,
        connectionType: 1,
        dataSourceId: null,
        extraUrl: null,
        factoryId: window.localStorage.factoryId,
        interfaceName: null,
        method: 1,
        requestBody: null,
        sqlScript: null
      }
      this.testForm = {
        params: null,
        callData: null
      }
      this.dialogLoading = false
      this.$refs.form.resetFields();
      this.$refs.testForm.resetFields();
    },
    testInvokeInterface() {
      this.$refs.form.validate(valid => {
        if (valid) {
          this.$refs.testForm.validate(vald => {
            if (vald) {
              this.form.param = this.testForm.params
              invokeInterTest(this.form).then(res => {
                this.testForm.callData = res.data
              })
            }else{
              return false
            }
          })
        } else {
          return false;
        }
      });
    }
  }
};
</script>

<style lang="scss" scoped>
.page-box {
  padding: 10px;
}
</style>
